package net.borderwars.map;

import java.awt.*;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

/**
 * @author Eric
 *         Date: Nov 25, 2003
 *         Time: 10:30:01 PM
 */

public class Line extends Line2D {
// ------------------------------ FIELDS ------------------------------

    double x1,
            x2,
            y1,
            y2;
    Point start = null;
    Point end = null;
    float slope;
    double intercept;

// --------------------------- CONSTRUCTORS ---------------------------

    public Line (double x1, double y1, double x2, double y2) {
        setLine (x1, y1, x2, y2);
    }

    public Line (int x1, int y1, int x2, int y2) {
        setLine (x1, y1, x2, y2);
    }

    public void setLine (double X1, double Y1, double X2, double Y2) {
        this.x1 = X1;
        this.x2 = X2;
        this.y1 = Y1;
        this.y2 = Y2;
        start = new Point (X1, Y1);
        end = new Point (X2, Y2);
        double rise = (y2 - y1);
        double run = x2 - x1;
        slope = (float) (rise / run);
        //  y = m * x + b
        // y/(m*x) = b
        intercept = y1 / (slope * x1);
    }

    public boolean isOn (Point p) {
        return isOn (p.x, p.y);
    }

    private boolean isOn (int x, int y) {
        int sy = (int) (slope * x + intercept);
        if (sy == y) {
            return true;
        }
        else {
            return (false);
        }

    }

// ------------------------ CANONICAL METHODS ------------------------

    public String toString () {
        Point a = new Point (x1, y1);
        Point b = new Point (x2, y2);
        return (a + "," + b);
    }

// ------------------------ INTERFACE METHODS ------------------------

// --------------------- Interface Shape ---------------------

    public Rectangle2D getBounds2D () {
        Rectangle r = new Rectangle ();
        r.add (getP1 ());
        r.add (getP2 ());
        return (r);
    }

// -------------------------- OTHER METHODS --------------------------

    public void draw (Graphics g) {
        g.drawLine ((int) x1, (int) y1, (int) x2, (int) y2);
    }

    public Point2D getP1 () {
        return new Point (x1, y1);
    }

    public Point2D getP2 () {
        return new Point (x2, y2);
    }

    public double getX1 () {
        return x1;
    }

    public double getX2 () {
        return x2;
    }

    public double getY1 () {
        return y1;
    }

    public double getY2 () {
        return y2;
    }

    private boolean inRange (Point p) {
        int maxx = Math.max (start.x, end.x);
        int minx = Math.min (start.x, end.x);

        int maxy = Math.max (start.y, end.y);
        int miny = Math.min (start.y, end.y);

        if (p.x <= maxx && p.x >= minx) {
            if (p.y <= maxy && p.y >= miny) {
                return (true);
            }

        }

        return (false);
    }

    /**
     * Return a point as the intersection of two lines -- called from a Line object
     * Returns null if the two lines do not interseect
     */
    public Location intersects (final Line line1) {

        int num = (int) ((this.y2 - this.y1) * (this.x1 - line1.x1) - (x2 - x1) * (this.y1 - line1.y1));

        int denom = (int) ((this.y2 - this.y1) * (line1.x2 - line1.x1) - (x2 - x1) * (line1.y2 - line1.y1));

        if (denom == 0) {
            return (null);
        }

        int x = (int) (line1.x1 + (line1.x2 - line1.x1) * num / denom);
        int y = (int) (line1.y1 + (line1.y2 - line1.y1) * num / denom);

        return new Location (x, y);
    }

    // Calculate the length of a line
    public int length () {
        return start.distance (end);  // Use the method from the Point class
    }
}
